Arguments/Values Passing

Function proclamations (function function-name ( arg-type1 arg-type2 ...) return-type) or its equivalents give the compiler the chance to generate compiled code so that arguments to the named functions and resulting values of the named functions will be passed via the C stack, thus increasing the efficiency of calls to these functions. Such arguments/values passing via the C stack is possible only if the called function is also defined in the same source file. This is because the code for the called function must have two entries: One entry for arguments/values passing via the C stack and another for ordinary arguments/values passing via the value stack. (An ordinary function has only the latter entry.) When the latter entry is used, the arguments on the value stack are pushed onto the C stack and then the former entry is used to execute the body of the function. On return from the function, the resulting value on the C stack is pushed onto the value stack. This means that ordinary calls to these functions are slower than calls to ordinary functions.


One of the merits of arguments/values passing via the C stack is that raw data stored in C-stack-allocated variables can be passed directly to other functions and raw data returned from functions may directly be saved in C-stack-allocated variables or may directly be used as arguments to another function. A good example of this follows.

    (eval-when (compile)
      (proclaim '(function tak (fixnum fixnum fixnum) fixnum)))

    (defun tak (x y z)
      (declare (fixnum x y z))
      (if (not (< y x))
          z
          (tak (tak (1- x) y z)
               (tak (1- y) z x)
               (tak (1- z) x y))))

    ;;; Call (tak 18 12 6).

When tak is called with the arguments 18, 12, and 6, the raw fixnum data of the arguments are set to the parameters x, y, z which are allocated on the C stack. After that, only raw data on the C stack are used to perform the execution: No cell pointers are newly allocated nor even referenced. Arguments and resulting values for recursive calls to tak are passed via the C stack, and the built-in functions < and 1- directly operate on the raw data. Only at the return from the top-level call of tak, the resulting raw data value (which happens to be 7 ) is reallocated on the heap. Note that both the function proclamation and the local fixnum declaration are necessary to obtain the optimal code. The function proclamation is necessary for arguments/values passing via the C stack and the fixnum declaration is necessary to allocate the parameters onto the C stack.